#include "teacher.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

static status TeaExtendCapcity(TeaManage* tea);
static status TeaInputMessage(TeaManage* tea,int i,int insertOrChange);
static status TeaChangeMessageByIndex(TeaManage* tea,int i);
static status TeaDelByIndex(TeaManage *tea,int i);
static status TeaIdIsExist(TeaManage* tea,int id,int* index,int findOrIfind);
static status TeaAccountIsOne(TeaManage* tea,char* account);
static status TeaIdIsOne(TeaManage* tea,int id);

status TeaInit(TeaManage* tea){

    assert(tea);

    Teacher* p = (Teacher*)malloc(sizeof(Teacher) * TEACHER_INIT_CAPCITY);
    if(!p) exit(OVERFLOW);

    tea->teacher = p;
    tea->numOfTea = 0;
    tea->capcity = TEACHER_INIT_CAPCITY;

    return OK;
}

//插入教师
status TeaInsert(TeaManage* tea,int i){

    assert(tea && (i>=1 && i<=tea->numOfTea+1));

    //判断是否进行扩容
    if(tea->numOfTea == tea->capcity)
        if(TeaExtendCapcity(tea) == ERROR)
            return ERROR;

    //进行数据后移
    Teacher* p1 = tea->teacher+i-1; //指向第i个地址
    Teacher* p2 = tea->teacher+tea->numOfTea-1; //指向最后一个地址

    for(;p2>=p1;p2--){

        *(p2+1) = *p2;
    }

    //输入信息
    TeaInputMessage(tea,i,TEA_INSERT);

    ++tea->numOfTea;

    return OK;
}

//输入信息两种情况 插入 修改
status TeaInputMessage(TeaManage* tea,int i,int insertOrChange){

    if(insertOrChange == TEA_INSERT)
        assert(tea && (i>=1 && i<=tea->numOfTea+1));
    else if(insertOrChange == TEA_CHANGE)
        assert(tea && (i>=1 && i<=tea->numOfTea));
    else return ERROR;

    int index = -1;
    char temp[TEMP_SIZE];

    while(1){

        printf("请输入账户(%d位 "TEAACCOUNT_FLAG" 开头)>",ACCOUNT_SIZE-1);
        memset(temp,0,TEMP_SIZE);
        scanf("%s",temp);

        //判断账户长度和开头
        if( (strlen(temp) == ACCOUNT_SIZE-1) && \
            (strncmp(temp,TEAACCOUNT_FLAG,strlen(TEAACCOUNT_FLAG)) == 0) ){

            if( (insertOrChange == TEA_INSERT) && \
                (TeaAccountIsExist(tea,temp,&index,TEA_IFIND) == NOTEXIST) ){

                memcpy((tea->teacher+i-1)->account,temp,ACCOUNT_SIZE);
                printf("账户输入成功\n");
                break;
            }
            else if(insertOrChange == TEA_CHANGE){

                //先输入数据
                memcpy((tea->teacher+i-1)->account,temp,ACCOUNT_SIZE);
                
                if(TeaAccountIsOne(tea,temp) == OK){

                    printf("账户输入成功\n");
                    break;
                }
            }
        }

        printf("输入信息有误\n");
    }

    while(1){

        printf("请输入密码(%d位及以内)>",PASSWD_SIZE-1);
        memset(temp,0,TEMP_SIZE);
        scanf("%s",temp);

        if(strlen(temp) <= PASSWD_SIZE-1){

            memcpy((tea->teacher+i-1)->passwd,temp,strlen(temp)+1);
            printf("密码输入成功\n");
            break;
        }

        printf("密码输入有误\n");
    }

    while(1){

        int id = 0;
        printf("请输入id(9位及以内)>");
        scanf("%d",&id);

        if(insertOrChange == TEA_INSERT){

            if(TeaIdIsExist(tea,id,&index,TEA_IFIND) == NOTEXIST){

                (tea->teacher+i-1)->id = id;
                printf("id输入成功\n");
                break;
            }
        }
        else if(insertOrChange == TEA_CHANGE){

            (tea->teacher+i-1)->id = id;

            if(TeaIdIsOne(tea,id) == OK){

                printf("id输入成功\n");
                break;
            }
        }

        printf("输入有误\n");
    }

    printf("请输入姓名>");
    memset(temp,0,TEMP_SIZE);
    scanf("%s",temp);
    strncpy((tea->teacher+i-1)->name,temp,NAME_SIZE);
    (tea->teacher+i)->name[NAME_SIZE-1] = '\0';

    while(1){

        int ageTemp;
        printf("请输入年龄>");
        scanf("%d",&ageTemp);

        if(ageTemp>0 && ageTemp<=150){

            (tea->teacher+i-1)->age = ageTemp;
            printf("年龄输入成功\n");
            break;
        }
    }

    return OK;
}

//修改信息 (根据位置)
static status TeaChangeMessageByIndex(TeaManage* tea,int i){

    assert(tea && (i>0 && i<=tea->numOfTea));

    return TeaInputMessage(tea,i,TEA_CHANGE);
}

//修改信息 (根据id)
status TeaChangeMessageById(TeaManage* tea,int id){

    assert(tea);

    int index = -1;
    if(TeaIdIsExist(tea,id,&index,TEA_FIND) == NOTEXIST)
        return ERROR;
    
    return TeaChangeMessageByIndex(tea,index+1);
}

static status TeaDelByIndex(TeaManage *tea,int i){

    assert(tea && (i>=1 && i<= tea->numOfTea));

    Teacher *p1 = tea->teacher+i-1;
    Teacher *p2 = tea->teacher+tea->numOfTea-1;

    for(++p1;p1<=p2;p1++){
        *(p1-1) = *p1;
    }

    --tea->numOfTea;

    return OK;
}

status TeaDelById(TeaManage* tea,int id){

    assert(tea);

    int index = -1;

    if(TeaIdIsExist(tea,id,&index,TEA_FIND) == NOTEXIST)
        return ERROR;

    return TeaDelByIndex(tea,index+1);
}

int TeaCompById(const void* p1,const void* p2){

    return (((Teacher*)p1)->id - ((Teacher*)p2)->id);
}

status TeaSortById(TeaManage* tea){

    assert(tea);

    qsort(tea->teacher,tea->numOfTea,sizeof(Teacher),TeaCompById);

    return OK;
}

status TeaShowAllById(TeaManage* tea,int id){

    assert(tea);

    int index = -1;

    if(TeaIdIsExist(tea,id,&index,TEA_FIND) == NOTEXIST)
        return ERROR;
        
    printf("账号\t\t密码\tid\t姓名\t年龄\n");

    Teacher* p = tea->teacher+index;

    printf("%s\t%s\t%d\t%s\t%d\n",p->account,p->passwd,p->id,p->name,p->age);

    return OK;
}

void TeaShowAllLess(TeaManage* tea){

    assert(tea);
        
    printf("id\t姓名\t年龄\n");

    for(int i = 0;i < tea->numOfTea;i++){

        Teacher *p = tea->teacher+i;
        printf("%d\t%s\t%d\n",p->id,p->name,p->age);
    }
}

void TeaShowAll(TeaManage* tea){

    assert(tea);
        
    printf("账号\t\t密码\tid\t姓名\t年龄\n");

    for(int i = 0;i < tea->numOfTea;i++){

        Teacher *p = tea->teacher+i;
        printf("%s\t%s\t%d\t%s\t%d\n",p->account,p->passwd,p->id,p->name,p->age);
    }
}

static status TeaExtendCapcity(TeaManage* tea){

    assert(tea);

    int newCapcity = tea->capcity + TEACHER_INCREASE;
    Teacher* p = (Teacher*)realloc(tea->teacher,sizeof(Teacher)*newCapcity);
    if(!p) exit(OVERFLOW);

    tea->teacher = p;
    tea->capcity = newCapcity;

    return OK;
}

//查找账户是否存在 两种情况 插入后移数据后判断输入的账号是否存在 普通查找，查看账号是否存在
status TeaAccountIsExist(TeaManage* tea,char* account,int* index,int findOrIfind){

    assert(tea && account);

    int j = (findOrIfind == TEA_FIND) ? (tea->numOfTea) : \
            ((tea->numOfTea>1) ? (tea->numOfTea+1) : (tea->numOfTea));

    for(int i = 0;i < j;i++){
        
        if(strcmp((tea->teacher+i)->account,account) == 0){

            *index = i;
            return EXIST;
        }
    }

    return NOTEXIST;
}

//查找id是否存在 两种情况 插入后移数据后判断输入的id是否存在 普通查找，查看id是否存在
static status TeaIdIsExist(TeaManage* tea,int id,int* index,int findOrIfind){

    assert(tea);

    int j = (findOrIfind == TEA_FIND) ? (tea->numOfTea) : \
            ((tea->numOfTea>1) ? (tea->numOfTea+1) : (tea->numOfTea));

    for(int i = 0;i < j;i++){
        
        if((tea->teacher+i)->id == id){

            *index = i;
            return EXIST;
        }
    }

    return NOTEXIST;
}

//判断修改完的账号 是否只有一份
static status TeaAccountIsOne(TeaManage* tea,char* account){

    assert(tea && account);

    int cnt = 0;

    for(int i = 0;i < tea->numOfTea;i++){

        if(strcmp((tea->teacher+i)->account,account) == 0)
            if(++cnt > 1) return ERROR;
    }

    return OK;
}

//判断修改完的id 是否只有一份
static status TeaIdIsOne(TeaManage* tea,int id){

    assert(tea);

    int cnt = 0;

    for(int i = 0;i < tea->numOfTea;i++){

        if((tea->teacher+i)->id == id)
            if(++cnt > 1) return ERROR;
    }

    return OK;
}

